#include "nec.hpp"

list<token> toks;

void lexanalyse(string file) {
	std::ifstream in(file.c_str());
	int line=0,col;
	//std::stringstream tok;
	string li;
	char tmp;
	while (std::getline(in,li)) {
		line++;
		col=0;
		while (col<li.length()) {
			if (isspace(li[col])) {
				col++;
				continue;
			}
			char const *const cur=li.c_str()+col;
			const int rem=li.length()-col;
			int len=1;
			if (is_letter(*cur)) {
				while (is_alnum(cur[len])) len++;
			} else if (isdigit(*cur)) {
				while (isdigit(cur[len])) len++;
				if (is_alnum(cur[len])) error(file,line,col,"names must begin with letter or _");
			} else switch(*cur) {
			case '(':
			case ')':
			case '[':
			case ']':
			case '{':
			case '}':
			case ';':
			case ',':
			case '?':
			case '~':
			case '.':
				break;
			case ':':
				if (cur[1]==':') len=2;
				break;
			case '+':
			case '&':
			case '|':
				if (cur[0]==cur[1] || cur[1]=='=') len=2;
				break;
			case '-':
				if (strchr("-=>",cur[1])) len=2;
				break;
			case '*':
			case '/':
			case '%':
			case '^':
			case '!':
			case '=':
				if (cur[1]=='=') len=2;
				break;
			case '<':
			case '>':
				if (cur[1]=='=') len=2;
				else if (cur[0]==cur[1]) {
					if (rem>2 && cur[2]=='=') len=3;
					else len=2;
				}
				break;
			case '\'':
				if (rem<3) error(file,line,col,"unexpected EOL");
				if (cur[1]=='\\') {
					if (rem<4 || cur[3]!='\'') error(file,line,col,"missing '");
					len=4;
				} else {
					if (cur[2]!='\'') error(file,line,col,"missing '");
					len=3;
				}
				break;
			case '"':
				len=0;
				while (++len<rem && cur[len]!='"')
					if (cur[len]=='\\') len++;
				if (++len>rem) error(file,line,col,"unexpected EOL");
				break;
			default:
				error (file,line,col,string("invalid character '")+*cur+'\'');
			}
			toks.push_back(token(li.substr(col,len),file,line,col));
			col+=len;

		}
		
	}
	
}

int main(int argc,char **argv) {
	lexanalyse(argv[1]);
	int line=1;
	std::cout<<"<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"sty.css\" /></head><body><p>";
	for (list<token>::iterator it=toks.begin();it!=toks.end();it++) {
		if (it->line>line) {
			std::cout<<"</p><p>";
			line=it->line;
		}
		std::cout<<"<span class=\""<<it->stype()<<"\" title=\""<<it->file<<':'<<it->line<<':'<<it->col<<"\">"<<it->str<<"</span>";
	}
}
